package com.ucode.cgms.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.ucode.cgms.mapper.CgmsAfterSaleCompanionOrderMapper;
import com.ucode.cgms.mapper.CgmsCompanionOrderMapper;
import com.ucode.cgms.service.CgmsAfterSaleCompanionOrderService;
import com.ucode.model.cgms.CgmsAfterSaleCompanionOrder;
import com.ucode.model.cgms.CgmsCompanionOrder;
import com.ucode.model.cgms.enums.CgmsAfterSaleCompanionOrderStatusEnum;
import com.ucode.model.cgms.enums.CgmsSysResultCodeEnum;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.IdentifyUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;

@Service
public class CgmsAfterSaleCompanionOrderServiceImpl implements CgmsAfterSaleCompanionOrderService {

    @Resource
    private CgmsAfterSaleCompanionOrderMapper cgmsAfterSaleCompanionOrderMapper;
    @Resource
    private CgmsCompanionOrderMapper cgmsCompanionOrderMapper;

    @Override
    public CgmsAfterSaleCompanionOrderMapper initMapper() {
        return cgmsAfterSaleCompanionOrderMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(CgmsAfterSaleCompanionOrder bean) {
        if(ObjUtil.isNull(bean.getId()))
            bean.setId(IdentifyUtils.getDefaultSnowflakeId());

        bean.setStatuz(CgmsAfterSaleCompanionOrderStatusEnum.APPLY.getStatus());

        CgmsCompanionOrder cgmsCompanionOrder = cgmsCompanionOrderMapper.selectByPrimaryKey(bean.getOrderId());
        if(ObjUtil.isNull(cgmsCompanionOrder) || cgmsCompanionOrder.getDeltag())
            throw new UcodeServiceException(CgmsSysResultCodeEnum.COMPANION_ORDER_NOT_EXISTS);

        bean.setPayStatementId(cgmsCompanionOrder.getPayOrderId());

        //计算退款金额
        //判断是否是最后一次售后
        if(ObjUtil.equals(bean.getQuantity(),(cgmsCompanionOrder.getQuantity() - cgmsCompanionOrder.getRefundQuantity()))){
            bean.setReturnAmount(NumberUtil.sub(cgmsCompanionOrder.getPayPrice(), cgmsCompanionOrder.getRefundAmount()));
        }else {
            //计算平均单价
            BigDecimal averagePayPrice  = NumberUtil.div(cgmsCompanionOrder.getPayPrice(), cgmsCompanionOrder.getQuantity());
            bean.setReturnAmount(NumberUtil.mul(averagePayPrice,bean.getQuantity()).setScale(2, RoundingMode.HALF_UP));
        }
        //退款金额
        if(bean.getReturnAmount().compareTo(BigDecimal.ZERO) <= 0){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_CREATE_FAIL_REFUND_QUANTITY_ERROR);
        }

        //更新订单售后状态,已存在申请售后，不允许再发起售后申请
        if(cgmsCompanionOrderMapper.updateAfterSaleState(bean.getOrderId(),true,bean.getQuantity()) == 0) {
            throw new UcodeServiceException(CgmsSysResultCodeEnum.COMPANION_ORDER_EXIST_AFTER_SALES_ORDER);
        }

        cgmsAfterSaleCompanionOrderMapper.insert(bean);
    }

    @Override
    public void cancel(Long id) {
        CgmsAfterSaleCompanionOrder bean = this.validate(id);
        if(!ObjUtil.equals(bean.getStatuz(),CgmsAfterSaleCompanionOrderStatusEnum.APPLY.getStatus())){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_APPLY);
        }

        if(cgmsAfterSaleCompanionOrderMapper.cancel(id) == 0){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_APPLY);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelByMember(Long userId,Long id) {
        CgmsAfterSaleCompanionOrder bean = this.validate(id, userId);
        if(!ObjUtil.equals(bean.getStatuz(),CgmsAfterSaleCompanionOrderStatusEnum.APPLY.getStatus())){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_APPLY);
        }

        if(cgmsAfterSaleCompanionOrderMapper.cancel(id) == 0){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_APPLY);
        }

        if(cgmsCompanionOrderMapper.updateAfterSaleState(bean.getOrderId(),false,0) == 0) {
            throw new UcodeServiceException(GlobalResultCodeEnum.FAILED);
        }
    }

    @Override
    public void deleteByMember(Long userId, Long id) {
        CgmsAfterSaleCompanionOrder bean = this.validate(id, userId);
        if(!ObjUtil.equals(bean.getStatuz(),CgmsAfterSaleCompanionOrderStatusEnum.BUYER_CANCEL.getStatus())){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_DELETE_ERROR);
        }

        cgmsAfterSaleCompanionOrderMapper.logicDeletePrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void audit(Long id, Integer statuz, Long handlerId, Integer handlerType, String handleNote) {

        if(!ObjUtil.equals(statuz,CgmsAfterSaleCompanionOrderStatusEnum.SELLER_AGREE.getStatus()) &&
                !ObjUtil.equals(statuz,CgmsAfterSaleCompanionOrderStatusEnum.SELLER_DISAGREE.getStatus()))
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);

        CgmsAfterSaleCompanionOrder bean = this.validate(id);
        if(!ObjUtil.equals(bean.getStatuz(),CgmsAfterSaleCompanionOrderStatusEnum.APPLY.getStatus())){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_APPLY);
        }


        CgmsAfterSaleCompanionOrder updateBean = new CgmsAfterSaleCompanionOrder();
        updateBean.setId(id);
        updateBean.setStatuz(statuz);
        updateBean.setHandlerId(handlerId);
        updateBean.setHandlerType(handlerType);
        updateBean.setHandleNote(handleNote);
        updateBean.setHandleTime(LocalDateTime.now());

        if(cgmsAfterSaleCompanionOrderMapper.updateAudit(updateBean) == 0){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_APPLY);
        }

        //同意售后
        if(ObjUtil.equals(statuz,CgmsAfterSaleCompanionOrderStatusEnum.SELLER_AGREE.getStatus())){

            CgmsCompanionOrder cgmsCompanionOrder = cgmsCompanionOrderMapper.selectByPrimaryKey(bean.getOrderId());
            if(ObjUtil.isNull(cgmsCompanionOrder) || cgmsCompanionOrder.getDeltag())
                throw new UcodeServiceException(CgmsSysResultCodeEnum.COMPANION_ORDER_NOT_EXISTS);

            //强校验一下，退款数量不能大于订单数量
            if(cgmsCompanionOrder.getRefundQuantity() + bean.getQuantity() > cgmsCompanionOrder.getQuantity()){
                throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
            }

            Boolean isAllAfterSales = cgmsCompanionOrder.getRefundQuantity() + bean.getQuantity() == cgmsCompanionOrder.getQuantity();
            int i = cgmsCompanionOrderMapper.updateAfterSaleResult(bean.getOrderId(),bean.getQuantity(),bean.getReturnAmount(),isAllAfterSales);
            if(i == 0)
                throw new UcodeServiceException(GlobalResultCodeEnum.FAILED);

            //事物提交之后，后置处理发起真实退款
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {

                @Override
                public void afterCompletion(int status) {
                    //事物成功提交后
                    if (status == TransactionSynchronization.STATUS_COMMITTED) {

                        //TODO 这里要发起退款

                    }else if(status == TransactionSynchronization.STATUS_ROLLED_BACK){
                        //事物回滚后
                    }
                }

            });

        }

        //拒绝售后
        if(ObjUtil.equals(statuz,CgmsAfterSaleCompanionOrderStatusEnum.SELLER_DISAGREE.getStatus())){
            if(cgmsCompanionOrderMapper.updateAfterSaleState(bean.getOrderId(),false,0) == 0) {
                throw new UcodeServiceException(GlobalResultCodeEnum.FAILED);
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refundSuccessAfterSale(Long id, Long refundStatementId, LocalDateTime refundTime, Integer refundAmount) {

        CgmsAfterSaleCompanionOrder bean = this.validate(id);

        if(!ObjUtil.equals(bean.getStatuz(),CgmsAfterSaleCompanionOrderStatusEnum.SELLER_AGREE.getStatus())){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_SELLER_AGREE);
        }

        //校验退款金额
        if(NumberUtil.mul(bean.getReturnAmount(),100).intValue() != refundAmount.intValue()){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_AMOUNT_NOT_EQUALS);
        }

        //如果已经回调过了，直接终止
        if(ObjUtil.isNotNull(bean.getRefundStatementId()) && !bean.getRefundStatementId().equals(0L)){
            return;
        }

        CgmsAfterSaleCompanionOrder updateBean = new CgmsAfterSaleCompanionOrder();
        updateBean.setId(id);
        updateBean.setSuccessTime(LocalDateTime.now());
        updateBean.setRefundStatementId(refundStatementId);
        updateBean.setHandleTime(refundTime);

        if(cgmsAfterSaleCompanionOrderMapper.updateRefundSuccess(updateBean) == 0){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.AFTERSALE_COMPANION_ORDER_STATUS_IS_NOT_SELLER_AGREE);
        }
    }


    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private CgmsAfterSaleCompanionOrderServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }


}
